001    /* $RCSfile: ISO9796Part1WithRSASignatureEngine.java,v $
002     * $Revision: 1.3 $
003     * $Date: 2003/10/04 19:18:38 $
004     * $Author: uwe_guenther $
005     * $State: Exp $
006     *
007     * Created on November 02, 2002 8:40 PM
008     *
009     * Copyright (C) 2002 Uwe Guenther <uwe@cscc.de>
010     *
011     * This file is part of the jhbci JCE-ServiceProvider. The jhbci JCE-
012     * ServiceProvider is a library, written in JavaTM, that should be 
013     * used in HBCI banking applications (clients and may be servers),
014     * to do cryptographic operations.
015     *
016     * The jhbci library is free software; you can redistribute it and/or
017     * modify it under the terms of the GNU Lesser General Public
018     * License as published by the Free Software Foundation; either
019     * version 2.1 of the License, or (at your option) any later version.
020     *
021     * The jhbci library is distributed in the hope that it will be useful,
022     * but WITHOUT ANY WARRANTY; without even the implied warranty of
023     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
024     * Lesser General Public License for more details.
025     *
026     * You should have received a copy of the GNU Lesser General Public
027     * License along with this library; if not, write to the Free Software
028     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
029     *
030     */
031    
032    package de.cscc.crypto.provider;
033    
034    import java.security.AlgorithmParameters;
035    import java.security.InvalidAlgorithmParameterException;
036    import java.security.InvalidKeyException;
037    import java.security.InvalidParameterException;
038    import java.security.PrivateKey;
039    import java.security.PublicKey;
040    import java.security.SecureRandom;
041    import java.security.SignatureException;
042    import java.security.SignatureSpi;
043    import java.security.spec.AlgorithmParameterSpec;
044    
045    /** 
046     * ISO9796Part1AndRSASignatureEngine Class.
047     *
048     * @author  <a href=mailto:uwe@cscc.de>Uwe Günther</a>
049     *
050     * @version $Revision: 1.3 $
051     */
052    public final class ISO9796Part1WithRSASignatureEngine 
053    extends SignatureSpi implements Cloneable {
054    
055        private ISO9796Part1WithRSASignatureImpl sig = 
056        new ISO9796Part1WithRSASignatureImpl();
057        
058        /** Creates new ISO9796Part1WithRSASignatureEngine.  */
059        public ISO9796Part1WithRSASignatureEngine() {
060            if (JHBCI.selfIntegrityChecking() == false) {
061                throw new SecurityException("JHBCI-Provider is tampered.");
062            }        
063        }
064    
065        /**
066         * Creates and returns a copy of this object.  
067         *
068         * @return a clone of this instance.
069         * @throws CloneNotSupportedException  if the object's class does not
070         * support the <code>Cloneable</code> interface. Subclasses
071         * that override the <code>clone</code> method can also
072         * throw this exception to indicate that an instance cannot
073         * be cloned.
074         */
075        public Object clone() throws CloneNotSupportedException {
076            ISO9796Part1WithRSASignatureEngine result =
077            (ISO9796Part1WithRSASignatureEngine) super.clone();
078            result.sig = 
079            (ISO9796Part1WithRSASignatureImpl) this.sig.clone();
080            return result;
081        }
082        
083        /**
084         * Indicates whether some other object is "equal to" this one.
085         *
086         * @param   obj   the reference object with which to compare.
087         * @return  <code>true</code> if this object is the same as the obj
088         *         argument; <code>false</code> otherwise.
089         * @see     #hashCode()
090         * @see     java.util.Hashtable
091         */
092        public boolean equals(Object obj) {
093            //Only for performance.
094            if (this == obj) {
095                return true;
096            } 
097            
098            //If obj == null then instanceof returns false, see JLS 15.20.2
099            if (!(obj instanceof ISO9796Part1WithRSASignatureEngine)) {
100                return false;
101            }
102            
103            ISO9796Part1WithRSASignatureEngine other = 
104            (ISO9796Part1WithRSASignatureEngine)obj;
105            
106            return this.sig.equals(other.sig);
107        }
108        
109        /**
110         * Returns a hash code value for the object. 
111         *
112         * @return  a hash code value for this object.
113         * @see     java.lang.Object#equals(java.lang.Object)
114         * @see     java.util.Hashtable
115         */
116        public int hashCode() {
117            int result = 17;
118            result = 37*result + this.sig.hashCode();
119            return result;
120        }
121        
122        /**
123         * Returns a string representation of the object. 
124         *
125         * @return  a string representation of the object.
126         */
127        public String toString() {
128            return this.sig.toString();
129        }
130        
131        /**
132         * Initializes this signature object with the specified
133         * private key for signing operations.
134         *
135         * @param privateKey the private key of the identity whose signature
136         * will be generated.
137         *
138         * @throws InvalidKeyException if the key is improperly encoded, parameters
139         * are missing, and so on.
140         */
141        protected void engineInitSign(PrivateKey privateKey) 
142        throws InvalidKeyException {
143            this.sig.initSign(privateKey);
144        }
145        
146        /**
147         * Initializes this signature object with the specified
148         * private key and source of randomness for signing operations.
149         *
150         * <p>This concrete method has been added to this previously-defined
151         * abstract class. (For backwards compatibility, it cannot be abstract.)
152         *
153         * @param privateKey the private key of the identity whose signature
154         * will be generated.
155         * @param random the source of randomness
156         *
157         * @throws InvalidKeyException if the key is improperly encoded, parameters 
158         * are missing, and so on.
159         */
160        protected void engineInitSign(PrivateKey privateKey, SecureRandom random) 
161        throws InvalidKeyException {
162            this.sig.initSign(privateKey, random);
163        }
164        
165        /**
166         * Initializes this signature object with the specified
167         * public key for verification operations.
168         *
169         * @param publicKey the public key of the identity whose signature is
170         * going to be verified.
171         *
172         * @throws InvalidKeyException if the key is improperly
173         * encoded, parameters are missing, and so on.
174         */
175        protected void engineInitVerify(PublicKey publicKey) throws InvalidKeyException {
176            this.sig.initVerify(publicKey);
177        }
178        
179        /**
180         * Updates the data to be signed or verified
181         * using the specified byte.
182         *
183         * @param value the byte to use for the update.
184         *
185         * @throws SignatureException if the engine is not initialized
186         * properly.
187         */
188        protected void engineUpdate(byte value) throws SignatureException {
189            this.sig.update(value);
190        }
191        
192        /**
193         * Updates the data to be signed or verified, using the
194         * specified array of bytes, starting at the specified offset.
195         *
196         * @param values the array of bytes
197         * @param offset the offset to start from in the array of bytes
198         * @param len the number of bytes to use, starting at offset
199         *
200         * @throws SignatureException if the engine is not initialized
201         * properly
202         * @throws NullPointerException if outbuf is null.
203         * @throws IllegalArgumentException if offset or len is negative, or the 
204         * sum of offset and len is greater than length of the values array.
205         */
206        protected void engineUpdate(byte[] values, int offset, int len) 
207        throws SignatureException {
208            this.sig.update(values, offset, len);
209        }
210        
211        /**
212         * Returns the signature bytes of all the data
213         * updated so far.
214         * The format of the signature depends on the underlying
215         * signature scheme.
216         *
217         * @return the signature bytes of the signing operation's result.
218         *
219         * @throws SignatureException if the engine is not initialized properly.
220         */
221        protected byte[] engineSign() throws SignatureException {
222            return this.sig.sign();
223        }
224        
225        /**
226         * Finishes this signature operation and stores the resulting signature
227         * bytes in the provided buffer <code>outbuf</code>, starting at
228         * <code>offset</code>.
229         * The format of the signature depends on the underlying
230         * signature scheme.
231         *
232         * <p>The signature implementation is reset to its initial state
233         * (the state it was in after a call to one of the
234         * <code>engineInitSign</code> methods)
235         * and can be reused to generate further signatures with the same private
236         * key.
237         *
238         * This method should be abstract, but we leave it concrete for
239         * binary compatibility.  Knowledgeable providers should override this
240         * method.
241         *
242         * @param outbuf buffer for the signature result.
243         *
244         * @param offset offset into <code>outbuf</code> where the signature is
245         * stored.
246         *
247         * @param len number of bytes within <code>outbuf</code> allotted for the
248         * signature.
249         * Both this default implementation and the SUN provider do not
250         * return partial digests. If the value of this parameter is less
251         * than the actual signature length, this method will throw a
252         * SignatureException.
253         * This parameter is ignored if its value is greater than or equal to
254         * the actual signature length.
255         *
256         * @return the number of bytes placed into <code>outbuf</code>
257         *
258         * @throws SignatureException if an error occurs or <code>len</code>
259         * is less than the actual signature length.
260         * @throws NullPointerException if outbuf is null.
261         * @throws IllegalArgumentException if offset or len is negative, or the 
262         * sum of offset and len is greater than length of the outbuf array.
263         */
264        protected int engineSign(byte[] outbuf, int offset, int len) 
265        throws SignatureException {
266            return this.sig.sign(outbuf, offset, len);
267        }    
268        
269        /**
270         * Verifies the passed-in signature.
271         *
272         * @param sigBytes the signature bytes to be verified.
273         *
274         * @return true if the signature was verified, false if not.
275         *
276         * @throws SignatureException if the engine is not initialized
277         * properly, or the passed-in signature is improperly encoded or
278         * of the wrong type, etc.
279         */
280        protected boolean engineVerify(byte[] sigBytes) throws SignatureException {
281            return this.sig.verify(sigBytes);
282        }
283        
284        /**
285         * Verifies the passed-in signature in the specified array
286         * of bytes, starting at the specified offset.
287         *
288         * <p> Note: Subclasses should overwrite the default implementation.
289         *
290         *
291         * @param sigBytes the signature bytes to be verified.
292         * @param offset the offset to start from in the array of bytes.
293         * @param len the number of bytes to use, starting at offset.
294         *
295         * @return true if the signature was verified, false if not.
296         *
297         * @throws SignatureException if the engine is not initialized
298         * properly, or the passed-in signature is improperly encoded or
299         * of the wrong type, etc.
300         */
301        protected boolean engineVerify(byte[] sigBytes, int offset, int len) 
302        throws SignatureException {
303            return this.sig.verify(sigBytes, offset, len);
304        }
305        
306        /**
307         * <p>This method is overridden by providers to initialize
308         * this signature engine with the specified parameter set.
309         *
310         * @param params the parameters
311         *
312         * @exception UnsupportedOperationException if this method is not
313         * overridden by a provider
314         *
315         * @throws InvalidAlgorithmParameterException if this method is
316         * overridden by a provider and the the given parameters
317         * are inappropriate for this signature engine
318         */
319        protected void engineSetParameter(AlgorithmParameterSpec params) 
320        throws InvalidAlgorithmParameterException {
321            this.sig.setParameter(params);
322        }
323        
324        /**
325         * <p>This method is overridden by providers to return the
326         * parameters used with this signature engine, or null
327         * if this signature engine does not use any parameters.
328         *
329         * <p>The returned parameters may be the same that were used to initialize
330         * this signature engine, or may contain a combination of default and
331         * randomly generated parameter values used by the underlying signature
332         * implementation if this signature engine requires algorithm parameters
333         * but was not initialized with any.
334         *
335         * @return the parameters used with this signature engine, or null if this
336         * signature engine does not use any parameters
337         *
338         * @throws UnsupportedOperationException if this method is
339         * not overridden by a provider
340         */
341        protected AlgorithmParameters engineGetParameters() {
342            return this.sig.getParameters();
343        }
344        
345        /**
346         * Sets the specified algorithm parameter to the specified
347         * value. This method supplies a general-purpose mechanism through
348         * which it is possible to set the various parameters of this object.
349         * A parameter may be any settable parameter for the algorithm, such as
350         * a parameter size, or a source of random bits for signature generation
351         * (if appropriate), or an indication of whether or not to perform
352         * a specific but optional computation. A uniform algorithm-specific
353         * naming scheme for each parameter is desirable but left unspecified
354         * at this time.
355         *
356         * @param param the string identifier of the parameter.
357         *
358         * @param value the parameter value.
359         *
360         * @exception InvalidParameterException if <code>param</code> is an
361         * invalid parameter for this signature algorithm engine,
362         * the parameter is already set
363         * and cannot be set again, a security exception occurs, and so on.
364         *
365         * @deprecated Replaced by {@link
366         * #engineSetParameter(java.security.spec.AlgorithmParameterSpec)
367         * engineSetParameter}.
368         */
369        protected void engineSetParameter(String param, Object value) 
370        throws InvalidParameterException {
371            throw new UnsupportedOperationException("Method deprecated.");
372        }
373        
374        /**
375         * Gets the value of the specified algorithm parameter.
376         * This method supplies a general-purpose mechanism through which it
377         * is possible to get the various parameters of this object. A parameter
378         * may be any settable parameter for the algorithm, such as a parameter
379         * size, or  a source of random bits for signature generation (if
380         * appropriate), or an indication of whether or not to perform a
381         * specific but optional computation. A uniform algorithm-specific
382         * naming scheme for each parameter is desirable but left unspecified
383         * at this time.
384         *
385         * @param param the string name of the parameter.
386         *
387         * @return the object that represents the parameter value, or null if
388         * there is none.
389         *
390         * @exception InvalidParameterException if <code>param</code> is an
391         * invalid parameter for this engine, or another exception occurs while
392         * trying to get this parameter.
393         *
394         * @deprecated
395         */
396        protected Object engineGetParameter(String param) 
397        throws InvalidParameterException {
398            throw new UnsupportedOperationException("Method deprecated.");
399        }
400        
401    }